package root;

/* 
Springboard - Copyright 2011
Allan Ellegaard - Nicolas Iseli Wulffeld - Thomas Hinrichs - Nicolas Nezzo
*/ 

import domain.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;

public class DataHandler implements Serializable {
    private ArrayList<Medlem> medlemsliste;
    private ArrayList<Medlem> springRytme;
    private ArrayList<Medlem> grandprix;
    private ArrayList<Medlem> springgymnastik;
    private ArrayList<Medlem> rytme;
    private ArrayList<Medlem> motionFitness; 
    
    public DataHandler() {
        medlemsliste = new ArrayList();
        springRytme = new ArrayList();
        grandprix = new ArrayList();
        springgymnastik = new ArrayList();
        rytme = new ArrayList();
        motionFitness = new ArrayList(); 
    }
    
    //Metodeområde 1:
    //I de følgende metoder oprettes de forskellige arrays.
    //Medlemsobjektet bliver skrevet til dem fra andre metoder.
    //Til sidst ryddes bufferen med .close()-funktionen.
    
    private void gemMedlemsliste() {
        try {                                                                               //Udtrykket i try afprøves.
            FileOutputStream fil = new FileOutputStream("medlemsliste.ser");        //Filens navn og placering sættes med FileOutputStream.
            ObjectOutputStream file = new ObjectOutputStream(fil);                          //ObjectOutputStream benyttes til at skrive til 'fil', da ArrayLists er objekter.

            file.writeObject(medlemsliste);                                                 //Her skrives arrayet til filen.
            file.close();                                                                   //Bufferen tømmes.
        } 
        
        catch(Exception e) {                                                                //Hvis try fejler, fanges fejlen (Exception) og gemmes på variablen 'e'.
            e.printStackTrace();                                                            //Fejlen skrives i konsollen.
            System.out.println("Medlemslisten kunne ikke gemmes.");                         //Venlig fejlmeddelse, for at vi nemmere kan identificere fejlen.
        } 
    }
    
    //Koden er mere eller mindre ens i det følgende stykke.
    //Eneste forskel er hvilken ArrayList og selvfølgelig hvilken fil der gemmes til
    
    private void gemSpringRytme() {
        try {
            FileOutputStream fil = new FileOutputStream("springrytme.ser");
            ObjectOutputStream file = new ObjectOutputStream(fil);

            file.writeObject(springRytme);
            file.close();
        } 
        
        catch(Exception e) {
            e.printStackTrace();
            System.out.println("Holdet Spring Rytme kunne ikke gemmes.");
        } 
    }
    
    private void gemGrandprix() {
        try {
            FileOutputStream fil = new FileOutputStream("grandprix.ser");
            ObjectOutputStream file = new ObjectOutputStream(fil);

            file.writeObject(grandprix);
            file.close();
        } 
        
        catch(Exception e) {
            e.printStackTrace();
            System.out.println("Holdet Grandprix kunne ikke gemmes.");
        } 
    }
    
    private void gemSpringgymnastik() {
        try {
            FileOutputStream fil = new FileOutputStream("springgymnastik.ser");
            ObjectOutputStream file = new ObjectOutputStream(fil);

            file.writeObject(springgymnastik);
            file.close();
        } 
        
        catch(Exception e) {
            e.printStackTrace();
            System.out.println("Holdet Springgymnastik kunne ikke gemmes.");
        } 
    }
    
    private void gemRytme() {
        try {
            FileOutputStream fil = new FileOutputStream("rytme.ser");
            ObjectOutputStream file = new ObjectOutputStream(fil);

            file.writeObject(rytme);
            file.close();
        } 
        
        catch(Exception e) {
            e.printStackTrace();
            System.out.println("Holdet Rytme kunne ikke gemmes.");
        } 
    }
    
    private void gemMotionFitness() {
        try {
            FileOutputStream fil = new FileOutputStream("motionfitness.ser");
            ObjectOutputStream file = new ObjectOutputStream(fil);

            file.writeObject(motionFitness);
            file.close();
        } 
        
        catch(Exception e) {
            e.printStackTrace();
            System.out.println("Holdet Motion Fitness kunne ikke gemmes.");
        } 
    }
    
    //Metodeområde 2:
    //Her tjekkes, om der allerede findes en medlemsfil/holdfil.
    //Hvis der gør, hentes de eksisterende data ind med en metoden HentX.
    //Herefter tilføjes medlemmet, og filen bliver gemt via metoden GemX.
    //'X' er her symbol for de forskellige metoder.

    public void tilfoejTilMedlemsliste(Medlem m) {
        File fil = new File("medlemsliste.ser");                                    //Der defineres hvilken fil der er tale om.
        
        if(fil.exists()) {                                                                  //Der tjekkes, om filen allerede eksisterer.
             medlemsliste = hentMedlemsliste();                                             //Hvis filen eksisterer, hentes indholdet med metoden HentMedlemsliste().
        }
        
        medlemsliste.add(m);                                                                //Medlemmet tilføjes.
        gemMedlemsliste();                                                                  //Medlemslisten gemmes.
    }
    
    //Igen er koden næsten den samme i det følgende, som i det ovenstående.
    //Eneste forskel er ArrayListen, filnavnet, og hvilken hent- og gem-metode der anvendes.

    public void tilfoejTilSpringRytme(Medlem m) {
        File fil = new File("springrytme.ser");
        
        if(fil.exists()) {
             springRytme = hentSpringRytme();
        }

        springRytme.add(m);
        gemSpringRytme();
    }
    
    public void tilfoejTilGrandprix(Medlem m) {
        File fil = new File("grandprix.ser");
        
        if(fil.exists()) {
             grandprix = hentGrandprix();
        }
        
        grandprix.add(m);
        gemGrandprix();
    }

    public void tilfoejTilSpringgymnastik(Medlem m) {
        File fil = new File("springgymnastik.ser");
        
        if(fil.exists()) {
             springgymnastik = hentSpringgymnastik();
        }
        
        springgymnastik.add(m);
        gemSpringgymnastik();
    }

    public void tilfoejTilRytme(Medlem m) {
        File fil = new File("rytme.ser");
        
        if(fil.exists()) {
             rytme = hentRytme();
        }
        
        rytme.add(m);
        gemRytme();
    }
    
    public void tilfoejTilMotionFitness(Medlem m) {
        File fil = new File("motionfitness.ser");
        
        if(fil.exists()) {
             motionFitness = hentMotionFitness();
        }
        
        motionFitness.add(m);
        gemMotionFitness();
    }
    
    //Metodeområde 3:
    //Her hentes informationer fra filerne.
    //Hvis ikke filen findes, bliver en exeption 'fanget', og skrevet med printStackTrace.
    
    public ArrayList hentMedlemsliste() {
        try {                                                                               //Udtrykket i try afprøves.
            FileInputStream fil = new FileInputStream("medlemsliste.ser");          //Filen medlemsliste.ser hentes ind med FileInputStream.
            ObjectInputStream input = new ObjectInputStream(fil);                           //Filens indhold læses ind som object med ObjectInputStream.
            
            this.medlemsliste = (ArrayList) input.readObject();                             //ArrayListen medlemsliste får indholdet af medlemsliste.ser lagt ind. Samtidig lover vi compileren, at der er tale om en ArrayList.
            input.close();                                                                  //Bufferen tømmes.
            
        }
        catch (Exception e) {                                                               //Hvis try fejler, fanges fejlen (Exception) og gemmes på variablen 'e'. 
            e.printStackTrace();                                                            //Fejlen skrives i konsollen.
            System.out.println("Medlemslisten er endnu ikke oprettet.");                    //Venlig fejlmeddelse til os selv, som gør det nemmere at finde fejlen.
        }
        
        return medlemsliste;
    }
    
    //Som i de to forgående metodeområder, er koden forneden næsten som den foroven.
    //Eneste forskel er ArrayListen og filnavnet.
    
    public ArrayList hentSpringRytme() {
        try {
            FileInputStream fil = new FileInputStream("springrytme.ser");
            ObjectInputStream input = new ObjectInputStream(fil);
            
            this.springRytme = (ArrayList) input.readObject();
            input.close();
            
        }
        catch (Exception e) {
            e.printStackTrace();
            System.out.println("Medlemslisten for Spring Rytme er endnu ikke oprettet.");
        }
        
        return springRytme;
    }
    
    public ArrayList hentGrandprix() {
        try {
            FileInputStream fil = new FileInputStream("grandprix.ser");
            ObjectInputStream input = new ObjectInputStream(fil);
            
            this.grandprix = (ArrayList) input.readObject();
            input.close();
            
        }
        catch (Exception e) {
            e.printStackTrace();
            System.out.println("Medlemslisten for Grand Prix er endnu ikke oprettet.");
        }
        
        return grandprix;
    }
    
    public ArrayList hentSpringgymnastik() {
        try {
            FileInputStream fil = new FileInputStream("springgymnastik.ser");
            ObjectInputStream input = new ObjectInputStream(fil);
            
            this.springgymnastik = (ArrayList) input.readObject();
            input.close();
            
        }
        catch (Exception e) {
            e.printStackTrace();
            System.out.println("Medlemslisten for Spring Gymnastik er endnu ikke oprettet.");
        }
        
        return springgymnastik;
    }
    
    public ArrayList hentRytme() {
        try {
            FileInputStream fil = new FileInputStream("rytme.ser");
            ObjectInputStream input = new ObjectInputStream(fil);
            
            this.rytme = (ArrayList) input.readObject();
            input.close();
            
        }
        catch (Exception e) {
            e.printStackTrace();
            System.out.println("Medlemslisten for Rytme er endnu ikke oprettet.");
        }
        
        return rytme;
    }
    
    public ArrayList hentMotionFitness() {
        try {
            FileInputStream fil = new FileInputStream("motionfitness.ser");
            ObjectInputStream input = new ObjectInputStream(fil);
            
            this.motionFitness = (ArrayList) input.readObject();
            input.close();
            
        }
        catch (Exception e) {
            e.printStackTrace();
            System.out.println("Medlemslisten for Motion Fitness er endnu ikke oprettet.");
        }
        
        return motionFitness;
    }
    
    //Metodeområde 4:
    //Her fjernes et medlem helt.
    //For at spare kode, kalder FjernFraMedlemsliste-metoden metoderne i Metodeområde 5.
    //Først hentes medlemsliste ind, hvorefter medlemmet fjernes fra alle holdlister.
    //Til sidst fjernes medlemmet selv ved brug af remove.
    //Som afslutning gemmes medlemslisten.
    
    public void FjernFraMedlemsliste(Medlem m) {
        this.medlemsliste = hentMedlemsliste();                                             //Medlemslisten hentes ind i ArrayListen medlemsliste.
        
        FjernFraSpringRytme(m);                                                             //I de følgende 5 metoder, fjernes medlemmet fra holdlisterne.
        FjernFraGranprix(m);
        FjernFraSpringgymnastik(m);
        FjernFraRytme(m);
        FjernFraMotionFitness(m);
        
        medlemsliste.remove(m);                                                             //Medlemmet fjernes fra ArrayListen medlemsliste.
        gemMedlemsliste();                                                                  //Medlemslisten gemmes med metoden GemMedlemsliste().
    }
    
    //Metodeområde 5:
    //Nedenfor fjernes medlemmet fra den enkelte holdliste.
    //Dette er nyttigt, hvis man ikke vil fjerne medlemmet helt, men f.eks. kun vil ændre hold.
    //Først hentes holdet. Herefter fjernes medlemmet fra holdet.
    //Til sidst gemmes holdlisten igen.

    public void FjernFraSpringRytme(Medlem m) {
        this.springRytme = hentSpringRytme();                                               //springRytme-ArrayListen opdateres med metoden HentSpringRytme().
        
        springRytme.remove(m);                                                              //Medlemmet fjernes fra springRytme-ArrayListen.
        gemSpringRytme();                                                                   //Listen gemmes med metoden GemSpringRytme().
    }
    
    //I de følgende fire metoder, er fremgangsmåden næsten den samme som i den ovenstående.
    //Forskellen er bare ArrayListen og Gem-metoden.
    
    public void FjernFraGranprix(Medlem m) {
        this.grandprix = hentGrandprix();
        
        grandprix.remove(m);
        gemMedlemsliste();
    }
    
    public void FjernFraSpringgymnastik(Medlem m) {
        this.springgymnastik = hentSpringgymnastik();
        
        springgymnastik.remove(m);
        gemMedlemsliste();
    }
    
    public void FjernFraRytme(Medlem m) {
        this.rytme = hentRytme();
        
        rytme.remove(m);
        gemMedlemsliste();
    }
    
    public void FjernFraMotionFitness(Medlem m) {
        this.motionFitness = hentMotionFitness();
        
        motionFitness.remove(m);
        gemMedlemsliste();
    }
    
    //Metodeområde 6:
    //Denne metode bruges til at redigere et medlem. Medlemmets nye dat bliver også gemt på holdene.
    //Først hentes medlemslisten og holdlisterne ind via metoder fra Metodeområde 3.
    //Herefter tjekkes om medlemmet findes.
    //Hvis medlemmet findes, tilføjes det opdaterede medlemsobjekt, og listerne gemmes.
    //Herefter fjernes det gamle medlem fra alle lister.
    //For at bryde for-loopet returnes en true-værdi, når medlemmet er fundet, opdateret, og det gamle er fjernet.
    
    
    public boolean RedigerMedlem(String cpr, String fornavn, String efternavn, String adresse, String telefon, String email) {
        medlemsliste = hentMedlemsliste();                                                  //Medlemslisten hentes ind med HentMedlemsliste()-metoden.
        springRytme = hentSpringRytme();                                                    //Holdlisterne hentes ind med deres egne Hent-metoder.
        grandprix = hentGrandprix();
        springgymnastik = hentSpringgymnastik();
        rytme = hentRytme();
        motionFitness = hentMotionFitness();
        
        for (int i = 0; i < medlemsliste.size(); i++) {                                     //Antallet af medlemmer i medlemsliste-ArrayListen tælles med en for-løkke.
           
            if(medlemsliste.get(i).getCpr().equalsIgnoreCase(cpr)) {                        //If-sætning, der påbegynder redigeringsprocessen, hvis medlemmets CPR-nummer matcher.
                Medlem m = (Medlem) medlemsliste.get(i);                                    //Det nuværende medlemsobjekts position hentes fra for-løkken.
                Medlem m2 = new Medlem(cpr, fornavn, efternavn, adresse, telefon, email);   //Det nye medlem gemmes på m2.
                medlemsliste.add(m2);                                                       //Det nye medlemsobjekt gemmes på medlemslisten med .add(m2).
                gemMedlemsliste();                                                          //Medlemslisten gemmes med GemMedlemsliste()-metoden.
                
                if (springRytme.contains(m)) {                                              //Der tjekkes, om det oprindelige medlemsobjekt findes på i ArrayListen springRytme.
                    
                    springRytme.add(m2);                                                    //Hvis medlemmet findes, tilføjes det nye medlemsobjekt.
                    gemSpringRytme();                                                       //ArrayListen for springRytme gemmes.
                }
                
                //Koden er stort set ens i de næste fire if-sætninger.
                //Eneste forskel er ArrayListen og Gem-metoden.
                
                if (grandprix.contains(m)) {
                    
                    grandprix.add(m2);
                    gemGrandprix();
                }
                
                if (springgymnastik.contains(m)) {
                    
                    springgymnastik.add(m2);
                    gemSpringgymnastik();
                }
                
                if (rytme.contains(m)) {
                    
                    rytme.add(m2);
                    gemRytme();
                }
              
                if (motionFitness.contains(m)) {
                    
                    motionFitness.add(m2);
                    gemMotionFitness();
                }
                
                FjernFraMedlemsliste(m);                                                    //Det oprindelige medlemsobjekt fjernes fra alle lister med metoden FjernFraMedlemsliste().
                
                return true;                                                                //True returneres for at bryde løkken.
                
            } else {                                                                        //Hvis medlemmet ikke findes, udskrives en lille fejlmeddelse i konsollen.
                System.out.println("Systemfejl: Medlemmet findes ikke.");                   //Fejlmeddelse med System.out.println.
                return false;                                                               //False returneres, da medlemmet ikke findes.
            }
        }
        return false;                                                                       //False returneres. Ellers opstår der en compiler-fejl.
    }
    
    //Metodeområde 7:
    //En simpel tæller, der bruges til at tælle medlemmer til GUI'et.
    
    public int medlemsCounter() {
        medlemsliste = hentMedlemsliste();                                                  //Medlemsliten hentes ind i ArrayListen medlemsliste fra HentMedlemsliste()-metoden.
        int count = medlemsliste.size();                                                    //Størrelsen af medlemsliste-ArrayListen gemmes i count.
        
        return count;                                                                       //Count returneres.
    }
}